// Shortcuts
var log = YAHOO.log;
var assert = YAHOO.util.Assert;

function trace(message) { YAHOO.log(message, "test"); }

// custom assertions

assert.isVisible = function(element, message) {
	assert.isFalse(YAHOO.util.Dom.hasClass(element, "invisible"), message);
};

assert.isNotVisible = function(element, message) {
	assert.isTrue(YAHOO.util.Dom.hasClass(element, "invisible"), message);
};

assert.isVisibleJq = function(element, message) {
//    assert.isFalse(YAHOO.util.Dom.hasClass(element, "invisible"), message);
    trace("testing for visibility");
    trace("element: "+element.html());
    assert.areNotEqual("none", element.css("display"), message);
};

assert.isNotVisibleJq = function(element, message) {
//    assert.isTrue(YAHOO.util.Dom.hasClass(element, "invisible"), message);
    trace("testing for invisibility");
    trace("element: "+element.html());
    assert.areEqual("none", element.css("display"), message);
};


// ************************************************************
// MODULE TESTS
// ************************************************************

flyui.flybasepub.PublicationWidget.ModuleTests = function(){};


/** 
 * Test that the contents of the flyui.flybasepub.PublicationWidget module have been defined.
 */
flyui.flybasepub.PublicationWidget.ModuleTests.testModuleContents = function() {
	
	try {
		flyui.info("Test \"==== flyui.flybasepub.PublicationWidget ModuleTests :: testModuleContents ====\" started.");
		
		assert.isNotUndefined(flyui.flybasepub.PublicationWidget, "flyui.flybasepub.PublicationWidget is undefined");	
		assert.isNotUndefined(flyui.flybasepub.PublicationWidget.Controller, "flyui.flybasepub.PublicationWidget.Controller is undefined");	
		assert.isNotUndefined(flyui.flybasepub.PublicationWidget.modelDefinition, "flyui.flybasepub.PublicationWidget.modelDefinition is undefined");	
		assert.isNotUndefined(flyui.flybasepub.PublicationWidget.DefaultRenderer, "flyui.flybasepub.PublicationWidget.DefaultRenderer is undefined");	
	} catch (error) {
        	throw new flyui.UnexpectedException("flyui.flybasepub.PublicationWidget.ModuleTests.testModuleContents", error);
    }
};


/**
 * TODO doc me
 */
flyui.flybasepub.PublicationWidget.ModuleTestCase = function (){
	try {
		var testCase = new YAHOO.tool.TestCase({
		
		name: "=== flyui.flybasepub.PublicationWidget ModuleTests ===",
		
		testModuleContents : flyui.flybasepub.PublicationWidget.ModuleTests.testModuleContents
		
		});
	
		return testCase;
	} catch (error) {
        	throw new flyui.UnexpectedException("flyui.flybasepub.PublicationWidget.ModuleTestCase", error);
    }
};

// ************************************************************
// Controller TESTS
// ************************************************************


flyui.flybasepub.PublicationWidget.ControllerTests = function() {};
 //

/** 
 * Set up function for the flyui.flybasepub.PublicationWidget.ControllerTests.
 * @param {String} endpointURL URL of flybasepub service
 * @param {YAHOO.tool.TestCase} testCase the test case context
 */
flyui.flybasepub.PublicationWidget.ControllerTests.setUpTest = function( endpointURL, testCase ) {
	try {
		trace("setUp test");
		// create a model
		testCase.model = new flyui.mvcutils.GenericModel2();
		testCase.model.setDefinition(flyui.flybasepub.PublicationWidget.modelDefinition);
	
		// create a service
		testCase.service = new flyui.flybasepub.Service(endpointURL);
		
		// create a dummy widget
		testCase.dummyWidget = {};
		
		// create a new controller instance
		testCase.controller = new flyui.flybasepub.PublicationWidget.Controller(testCase.model, testCase.service, testCase.dummyWidget);
		
	} catch (e) {
		flyui.err("setUp error, "+e.name+", "+e.message);
	}
};


/** 
 * Tear down function for the flyui.flybasepub.PublicationWidget.ControllerTests.
 * @param {YAHOO.tool.TestCase} testCase the test case context
 */
flyui.flybasepub.PublicationWidget.ControllerTests.tearDownTest = function( testCase ) {
	try {
		trace("tearDown test");
	} catch (e) {
		flyui.err("tearDown error, "+e.name+", "+e.message);
	}
};


/**
 * Test the model definition and initialisation.
 * @synchronous
 */
flyui.flybasepub.PublicationWidget.ControllerTests.testModelInit = function( testCase ) {
	flyui.info("Test \"==== flyui.flybasepub.PublicationWidget ControllerTests :: testModelInit ====\" started.");

	// create a model
	var model = testCase.model;

	// check the model properties
	assert.areEqual("READY", model.get("STATE"));
	assert.isNull(model.get("RESULTS"));
	assert.isNull(model.get("ERRORMESSAGE"));
	assert.isNull(model.get("QUERY"));

};


/**
 * Test the Controller class constructor.
 * @param {YAHOO.tool.TestCase} testCase the test case context
 * @synchronous
 */
flyui.flybasepub.PublicationWidget.ControllerTests.testControllerConstructor = function( testCase ) {
	flyui.info("Test \"==== flyui.flybasepub.PublicationWidget ControllerTests :: testControllerConstructor ====\" started.");

	// create a new controller instance
	var controller = testCase.controller;

	// check the API
	assert.isNotUndefined(controller.findPublicationsByFlybaseGeneID);
	//assert.isNotUndefined(controller.findPublicationsByAnyName);
	
};

/**
 * TODO doc me
 * @asynchronous
 */
flyui.flybasepub.PublicationWidget.ControllerTests.test_findPublicationsByFlybaseGeneID = function( testCase ) {

	flyui.info("Test \"==== flyui.flybasepub.PublicationWidget ControllerTests :: test_findImagesByflybasepubGeneName ====\" started.");

	// convenience variables
	var controller = testCase.controller;
	var model = testCase.model;
	
	var success = function(images) {
		trace("success case, resume test runner");
		testCase.resume();
	};
	
	var failure = function(response) {
		trace("failure case, resume test runner");
		testCase.resume(function() {
			assert.fail("request failed, status "+response.status+" "+response.statusText);
		});
	};
	
	// call the private method implementing the find function
	controller._findPublicationsByFlybaseGeneID("foo", success, failure);
	
	// check the model state property
	assert.areEqual("PENDING", model.get("STATE"));
	
	// check the model query property
	assert.areEqual("foo", model.get("QUERY"));
	
	trace("suspend test runner (hang here means problem)");
	testCase.wait();	
	
};


/**
 * TODO doc me
 */
flyui.flybasepub.PublicationWidget.ControllerTests.test_findPublicationsSuccess = function (testCase) {
	flyui.info("Test \"==== flyui.flybasepub.PublicationWidget ControllerTests :: test_findPublicationsSuccess ====\" started.");

	// convenience variables
	var controller = testCase.controller;
	var model = testCase.model;
	
	// fake up the state as pending
	model.set("STATE", "PENDING");
	
	// fake up a result set
	var publications = [];
	
	// make the callback
	controller._findPublicationsSuccess(publications);
	
	// check the state
	assert.areEqual("READY", model.get("STATE"));
	
	// check the results
	var results = model.get("RESULTS");
	assert.isNotUndefined(results);
	assert.isNotUndefined(results.length);
	assert.areEqual(0, results.length);
	
};

/**
 * TODO doc me
 */

flyui.flybasepub.PublicationWidget.ControllerTests.test_findPublicationsFailure = function (testCase) {
	flyui.info("Test \"==== flyui.flybasepub.PublicationWidget ControllerTests :: test_findPublicationsFailure ====\" started.");

	var controller = testCase.controller;
	var model = testCase.model;

	// fake up the state as pending
	model.set("STATE", "PENDING");
		
	// make the call
	var response = {status:999, statusText:"dummy error for testing"};
	controller._findPublicationsFailure(response);

	// check the state
	assert.areEqual("SERVERERROR", model.get("STATE"));
	
	// check the error message
	var msg = model.get("ERRORMESSAGE");
	trace("error message: "+msg);
	assert.isNotNull(msg);
};


/** 
 * Construct a YUI test case for the flyui.flybasepub.PublicationWidget ControllerTests.
 * @param {String} endpointURL URL of service
 * @return a YUI test case
 * @type YAHOO.tool.TestCase
 */
flyui.flybasepub.PublicationWidget.ControllerTestCase = function( endpointURL ) {
	
	var testCase = new YAHOO.tool.TestCase({
		
		name: "=== flyui.flybasepub.PublicationWidget ControllerTests ===",
		
		setUp : function() {
			flyui.flybasepub.PublicationWidget.ControllerTests.setUpTest(endpointURL, this);
		},
		
		tearDown : function() {
			flyui.flybasepub.PublicationWidget.ControllerTests.tearDownTest(this);
		},
		
		testModelInit : function() {
			flyui.flybasepub.PublicationWidget.ControllerTests.testModelInit(this);
		},
		
		testControllerConstructor : function() {
			flyui.flybasepub.PublicationWidget.ControllerTests.testControllerConstructor(this);
		},
				
		test_findPublicationsByFlybaseGeneID : function() {
			flyui.flybasepub.PublicationWidget.ControllerTests.test_findPublicationsByFlybaseGeneID(this);
		},
		
		test_findPublicationsSuccess : function() {
			flyui.flybasepub.PublicationWidget.ControllerTests.test_findPublicationsSuccess(this);
		},
		
		test_findPublicationsFailure : function() {
			flyui.flybasepub.PublicationWidget.ControllerTests.test_findPublicationsFailure(this);
		}
		
	});
	
	return testCase;
	
};

// ************************************************************
// Default Render TESTS
// ************************************************************


flyui.flybasepub.PublicationWidget.DefaultRendererTests = function() {};


/** 
 * Set up function for the flyui.flybasepub.PublicationWidget DefaultRendererTests.
 * @param {YAHOO.tool.TestCase} testCase the test case context
 */
flyui.flybasepub.PublicationWidget.DefaultRendererTests.setUpTest = function( testCase ) {
	try {
		trace("setUp test");
		
		trace("create a model");
		testCase.model = new flyui.mvcutils.GenericModel2();
		testCase.model.setDefinition(flyui.flybasepub.PublicationWidget.modelDefinition);
		
		trace("create an element for the renderer");
		testCase.renderPane = document.createElement("div");
		
		trace("put the renderer's div into the dom");
		document.body.appendChild(testCase.renderPane);
		
		trace("create a renderer");
		testCase.renderer = new flyui.flybasepub.PublicationWidget.DefaultRenderer();
		testCase.renderer.setCanvas(testCase.renderPane);
		
		trace("connect the renderer the model");
		testCase.renderer.connect(testCase.model);
				
	} catch (e) {
		flyui.err("setUp error, "+e.name+", "+e.message);
	}
};


/** 
 * Tear down function for the flyui.flybasepub.PublicationWidget DefaultRendererTests.
 * @param {YAHOO.tool.TestCase} testCase the test case context
 */
flyui.flybasepub.PublicationWidget.DefaultRendererTests.tearDownTest = function( testCase ) {
	try {
		trace("tearDown test");
		
		trace("remove the renderer element from the dom");
		document.body.removeChild(testCase.renderPane); 
		
	} catch (e) {
		flyui.err("tearDown error, "+e.name+", "+e.message);
	}
};


/**
 * TODO doc me
 */
flyui.flybasepub.PublicationWidget.DefaultRendererTests.testAPI = function( testCase ) {
	flyui.info("Test \"==== flyui.flybasepub.PublicationWidget DefaultRenderer Tests :: testAPI ====\" started.");
		
	var renderer = testCase.renderer;
	
	assert.isNotUndefined(renderer);
	assert.isNotUndefined(renderer.connect);

	assert.isNotUndefined(renderer._onStateChanged);
	assert.isNotUndefined(renderer._onQueryChanged);
	assert.isNotUndefined(renderer._onResultsChanged);
	assert.isNotUndefined(renderer._onErrorMessageChanged);

	// check pane fields
	assert.isNotUndefined(renderer._canvas);
	assert.isNotUndefined(renderer._pendingPane);
	assert.isNotUndefined(renderer._messagePane);
	assert.isNotUndefined(renderer._resultsSummaryPane);
	assert.isNotUndefined(renderer._resultsPane);

};

/**
 * TODO doc me
 */
flyui.flybasepub.PublicationWidget.DefaultRendererTests.testMainComponents = function( testCase ) {
	flyui.info("Test \"==== flyui.flybasepub.PublicationWidget DefaultRenderer Tests :: testMainComponents ====\" started.");

	var renderPane = testCase.renderPane;
	var renderer = testCase.renderer;
	
	var children = renderPane.childNodes;
	trace(renderPane.innerHTML);
	for ( var i=0; i<children.length; i++ ) {
		trace("found child: "+children[i]);
	}
	assert.areEqual(5, children.length, "number of child elements not as expected");
	
	trace("check first DIV is hidden'");
	var pendingPane = children[0];
	assert.isNotVisible(pendingPane, "pending pane should be invisible");
//	assert.areEqual(1, pendingPane.childNodes.length);
//	assert.areEqual("Pending...", pendingPane.childNodes[0].innerHTML);
	
	trace("Check 2nd DIV is invisible and contains text 'this should never be displayed'");
	assert.isNotVisible(children[1], "Message pane should be invisible");
	assert.areEqual("this should never be displayed", children[1].innerHTML);

	trace("Check 3rd DIV is invisible");
	assert.isNotVisible(children[2], "Results summary pane should be invisible");

	trace("Check 4th DIV is invisible");
	assert.isNotVisible(children[3], "Results pane should be invisible");

//	trace("Check 2nd DIV using Yahoo selector for access");
//	var divs = YAHOO.util.Selector.query("div", renderPane);
//	assert.isNotVisible(divs[1], "Message div should be invisible");
//	assert.areEqual("this should never be displayed", divs[1].innerHTML);
	
};

/**
 * TODO doc me
 */
flyui.flybasepub.PublicationWidget.DefaultRendererTests.testModelStateChangeToPending = function( testCase ) {
	flyui.info("Test \"==== flyui.flybasepub.PublicationWidget DefaultRenderer Tests :: testModelStateChangeToPending ====\" started.");
	
	var model = testCase.model;	
	var renderer = testCase.renderer;
	
	trace("set the model state to pending");
	model.set("STATE", "PENDING");
	
	trace("test visibilities");
	    
    var visibles = [ 
        "_pendingPane" 
    ];

    for (var i=0; i<visibles.length; i++) {
        assert.isVisibleJq(renderer[visibles[i]], visibles[i]+" is not visible");
    }
    
    var invisibles = [
        "_messagePane", 
        "_resultsSummaryPane", 
        "_resultsPane"
    ];

    for (var i=0; i<invisibles.length; i++) {
        assert.isNotVisibleJq(renderer[invisibles[i]], invisibles[i]+" is visible");
    }
};


/**
 * TODO doc me
 */
flyui.flybasepub.PublicationWidget.DefaultRendererTests.testModelStateChangeToReady = function( testCase ) {
	flyui.info("Test \"==== flyui.flybasepub.PublicationWidget DefaultRenderer Tests :: testModelStateChangeToReady ====\" started.");
	
	var model = testCase.model;
	var renderer = testCase.renderer;
	
	trace("set the model state to ready");
	model.set("STATE", "READY");
	
	trace("test visibilities");
	    
    var visibles = [ 
        "_resultsSummaryPane" 
    ];

    for (var i=0; i<visibles.length; i++) {
        assert.isVisibleJq(renderer[visibles[i]], visibles[i]+" is not visible");
    }
    
    var invisibles = [
        "_messagePane",
        "_pendingPane"
    ];

    for (var i=0; i<invisibles.length; i++) {
        assert.isNotVisibleJq(renderer[invisibles[i]], invisibles[i]+" is visible");
    }
};

/**
 * TODO doc me
 */
flyui.flybasepub.PublicationWidget.DefaultRendererTests.testModelStateChangeToServerError = function( testCase ) {
	flyui.info("Test \"==== flyui.flybasepub.PublicationWidget DefaultRenderer Tests :: testModelStateChangeToServerError ====\" started.");
	
	var model = testCase.model;
	var renderer = testCase.renderer;
		
	trace("set the model state to pending");
	model.set("STATE", "PENDING");	
	
	trace("set the model state to server error");
	model.set("STATE", "SERVERERROR");
	
	trace("test visibilities");
	
	var visibles = [ 
        "_messagePane" 
    ];

    for (var i=0; i<visibles.length; i++) {
        assert.isVisibleJq(renderer[visibles[i]], visibles[i]+" is not visible");
    }
    
    var invisibles = [
        "_resultsSummaryPane",
        "_pendingPane",
        "_resultsPane"
    ];

    for (var i=0; i<invisibles.length; i++) {
        assert.isNotVisibleJq(renderer[invisibles[i]], invisibles[i]+" is visible");
    }
	
};

/**
 * TODO doc me
 */
flyui.flybasepub.PublicationWidget.DefaultRendererTests.testModelStateChangeToUnexpectedError = function( testCase ) {
	flyui.info("Test \"==== flyui.flybasepub.PublicationWidget DefaultRenderer Tests :: testModelStateChangeToUnexpectedError ====\" started.");
	
	var model = testCase.model;
	var renderer = testCase.renderer;
	
	trace("set the model state to pending");
	model.set("STATE", "PENDING");	
	
	trace("set the model state to unexpected error");
	model.set("STATE", "UNEXPECTEDERROR");
	
	trace("test visibilities");
	
	var visibles = [ 
        "_messagePane" 
    ];

    for (var i=0; i<visibles.length; i++) {
        assert.isVisibleJq(renderer[visibles[i]], visibles[i]+" is not visible");
    }
    
    var invisibles = [
        "_resultsSummaryPane",
        "_pendingPane",
        "_resultsPane"
    ];

    for (var i=0; i<invisibles.length; i++) {
        assert.isNotVisibleJq(renderer[invisibles[i]], invisibles[i]+" is visible");
    }
	
};

flyui.flybasepub.PublicationWidget.DefaultRendererTests.testResultFor_FBgn0004372 = function( testCase ) {
	flyui.info("Test \"==== flyui.flybasepub.PublicationWidget DefaultRenderer Tests :: testResultFor_FBgn0004372 ====\" started.");
	
	var renderPane = testCase.renderPane;
	var model = testCase.model;
	var children = renderPane.childNodes;
	var summaryPane = children[2];
	var resultsPane = children[3];
	var testData = new flyui.flybasepub.Service.TestData;
	var publications = [testData.FBgn0004372];
	
	var query = new flyui.flybase.Gene();
	query.flybaseID = "FBgn0004372";
		
	trace("set the model query");
	model.set("QUERY", query);
	
	trace("set the model results");
	model.set("RESULTS", publications);
	
    trace("set the state ready");
    model.set("STATE", "READY");
    
};

/** 
 * Construct a YUI test case for the flyui.flybasepub.PublicationWidget DefaultRendererTests.
 * @return a YUI test case
 * @type YAHOO.tool.TestCase
 */
flyui.flybasepub.PublicationWidget.DefaultRendererTestCase = function() {
	
	var testCase = new YAHOO.tool.TestCase({
		
		name: "=== flyui.flybasepub.PublicationWidget DefaultRenderer Tests ===",
		
		setUp : function() {
			flyui.flybasepub.PublicationWidget.DefaultRendererTests.setUpTest(this);
		},
		
		tearDown : function() {
			flyui.flybasepub.PublicationWidget.DefaultRendererTests.tearDownTest(this);
		},
		
		testAPI : function() {
			flyui.flybasepub.PublicationWidget.DefaultRendererTests.testAPI(this);
		},

		testModelStateChangeToPending : function(){
			flyui.flybasepub.PublicationWidget.DefaultRendererTests.testModelStateChangeToPending(this);
		},
		
		testModelStateChangeToReady : function(){
			flyui.flybasepub.PublicationWidget.DefaultRendererTests.testModelStateChangeToReady(this);
		},
		
		testModelStateChangeToServerError : function(){
			flyui.flybasepub.PublicationWidget.DefaultRendererTests.testModelStateChangeToServerError(this);
		},
		
		testModelStateChangeToUnexpectedError : function() {
			flyui.flybasepub.PublicationWidget.DefaultRendererTests.testModelStateChangeToUnexpectedError(this);
		},
		
		testResultFor_FBgn0004372: function() {
			flyui.flybasepub.PublicationWidget.DefaultRendererTests.testResultFor_FBgn0004372(this);
		},
				
	});
	
	return testCase;
	
};



// ************************************************************
// TEST SUITE AND RUNNER
// ************************************************************


/** 
 * Construct a YUI test suite for the flyui.flybasepub.PublicationWidget module.
 * @param {String} endpointURL URL of flybase data
 * @return a YUI test suite
 * @type YAHOO.tool.TestSuite
 */
flyui.flybasepub.PublicationWidget.TestSuite = function(endpointURL) {
	try {
		var suite = new YAHOO.tool.TestSuite("== flyui.flybasepub.PublicationWidget Test Suite ==");
		suite.add(flyui.flybasepub.PublicationWidget.ModuleTestCase());
		suite.add(flyui.flybasepub.PublicationWidget.ControllerTestCase(endpointURL));
		suite.add(flyui.flybasepub.PublicationWidget.DefaultRendererTestCase());
		return suite;
	} catch (error) {
        	throw new flyui.UnexpectedException("flyui.flybasepub.PublicationWidget.TestSuite", error);
    }
};


/** 
 * Run the flyui.flybasepub.PublicationWidget test suite.
 * @param {String} endpointURL URL of flybase data
 */
flyui.flybasepub.PublicationWidget.runTests = function(endpointURL) {
	try {
		trace("flyui.flybasepub.PublicationWidget :: running tests");
		YAHOO.tool.TestRunner.clear();
		YAHOO.tool.TestRunner.add(flyui.flybasepub.PublicationWidget.TestSuite(endpointURL));
		YAHOO.tool.TestRunner.run();
	} catch (error) {
        	throw new flyui.UnexpectedException("flyui.flybasepub.PublicationWidget.runTests", error);
    }
};